package com.chenfan.mcn.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chenfan.common.exception.BusinessException;
import com.chenfan.mcn.enums.BusinessCommissionEnum;
import com.chenfan.mcn.exception.McnErrorCode;
import com.chenfan.mcn.extension.Res;
import com.chenfan.common.extension.validation.groups.Add;
import com.chenfan.common.extension.validation.groups.Modify;
import com.chenfan.mcn.model.BusinessCommission;
import com.chenfan.mcn.model.BusinessCommissionDetail;
import com.chenfan.mcn.model.BusinessCommissionDetailTemporary;
import com.chenfan.mcn.model.McnPage;
import com.chenfan.mcn.model.dto.*;
import com.chenfan.mcn.model.vo.*;
import com.chenfan.mcn.service.BusinessCommissionDetailTemporaryService;
import com.chenfan.mcn.service.BusinessCommissionService;
import com.chenfan.mcn.utils.BusinessAssert;
import com.chenfan.mcn.extension.excel.ExcelUtils;
import com.chenfan.privilege.common.config.SearchAuthority;
import com.chenfan.mcn.model.common.PageInfo;
import com.chenfan.privilege.common.config.UrlAuth;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Objects;

/**
 * 商务提成
 *
 * @Author liuyang
 * @Date 2021/6/7
 * @Time 13:50
 * @Version V1.0
 **/
@Slf4j
@RestController
@RequestMapping("/business/commission")
public class BusinessCommissionController {

    @Autowired
    private BusinessCommissionService businessCommissionService;

    @Autowired
    private BusinessCommissionDetailTemporaryService temporaryService;

    /**
     * 添加合同（确认）
     *
     * @param addContract {@link AddContract}
     * @return {@link String}
     */
    @PostMapping(value = "/addContract", produces = {"application/json;charset=UTF-8"})
    public Res<String> addContract(@Validated @RequestBody AddContract addContract) {
        return Res.ok(temporaryService.addContract(addContract));
    }


    /**
     * 添加合同（全选并确认）
     *
     * @param allContract {@link IncomeContractSearchDTO}
     * @return {@link String}
     */
    @PostMapping(value = "/selectAllAndConfirm", produces = {"application/json;charset=UTF-8"})
    public Res<String> selectAllAndConfirm(@RequestBody ExcutionOrderSearchDTO allContract) {
        return Res.ok(temporaryService.selectAllAndConfirm(allContract));
    }


    /**
     * 切换季度
     *
     * @param quarterCode   季度编号
     * @param temporaryCode 临时表编号
     * @return {@link Res}
     */
    @GetMapping(value = "/switchQuarter", produces = {"application/json;charset=UTF-8"})
    public Res<Object> switchQuarter(String quarterCode, String temporaryCode) {
        temporaryService.switchQuarter(quarterCode, temporaryCode);
        return Res.ok();
    }


    /**
     * 商务提成列表
     *
     * @param page                  {@link McnPage}
     * @param businessCommissionDTO {@link BusinessCommissionDTO}
     * @return {@link Res}
     */
    @GetMapping(value = "/getList", produces = {"application/json;charset=UTF-8"})
    @UrlAuth({"commerceCommission_search"})
    public Res<Page<BusinessCommissionVO>> getList(McnPage<BusinessCommissionVO> page, @SearchAuthority(filterCustomer = false) BusinessCommissionDTO businessCommissionDTO) {
        return Res.ok(businessCommissionService.getList(page, businessCommissionDTO));
    }


    /**
     * 新建页提成明细列表
     *
     * @param page                分页
     * @param detailListSearchDTO 筛选条件
     * @return {@link BusinessCommissionDetailList}
     */
    @GetMapping(value = "/detailList", produces = {"application/json;charset=UTF-8"})
    public Res<BusinessCommissionDetailList> detailList(McnPage<BusinessCommissionDetailTemporary> page, DetailListSearchDTO detailListSearchDTO) {
        return Res.ok(temporaryService.detailList(page, detailListSearchDTO));
    }


    /**
     * 季度编号下拉选项
     *
     * @return List
     */
    @GetMapping(value = "getQuarterCode", produces = {"application/json;charset=UTF-8"})
    public Res<List<String>> getQuarterCode() {
        return Res.ok(businessCommissionService.getQuarterCode());
    }


    /**
     * 批量删除(新增)
     *
     * @param ids {@link List<Long>}
     * @return {@link Res}
     */
    @PostMapping(value = "batchDelete", produces = {"application/json;charset=UTF-8"})
    public Res<Object> batchDelete(@RequestBody List<Long> ids) {
        Assert.notEmpty(ids, "请选择要删除的明细");
        return Res.ok(temporaryService.batchDelete(ids));
    }

    /**
     * 导入批量保存
     *
     * @return {@link Res}
     */
    @PostMapping(value = "/excel/batchSave/{id}", produces = {"application/json;charset=UTF-8"})
    @UrlAuth({"commerceCommission_toLead"})
    public Res<String> importBatchSave(@PathVariable Long id, @RequestParam MultipartFile multipartFile) {
        BusinessAssert.notNull(id, McnErrorCode.PARAM_ERROR, "提成单ID不能为空");
        BusinessCommission businessCommission = businessCommissionService.getById(id);
        BusinessAssert.notNull(businessCommission, McnErrorCode.DATA_NOT_FOUND, "查询不到提成单");
        List<BusinessCommissionBatchSaveDTO> inputList = null;
        try {
            inputList = ExcelUtils.importExcel(multipartFile, BusinessCommissionBatchSaveDTO.class);
        } catch (Exception e) {
            throw new BusinessException(McnErrorCode.IMPORT_EXCEL_FAILED);
        }
        BusinessAssert.notEmpty(inputList, McnErrorCode.IMPORT_CONTENT_EMPTY);
        return Res.ok(businessCommissionService.importBatchSave(businessCommission, inputList));
    }

    /**
     * 导入批量删除
     *
     * @return {@link Res}
     */
    @PostMapping(value = "/excel/batchDelete/{id}", produces = {"application/json;charset=UTF-8"})
    @UrlAuth({"commerceCommission_delete"})
    public Res<String> importBatchDelete(@PathVariable Long id, @RequestParam MultipartFile multipartFile) {
        BusinessAssert.notNull(id, McnErrorCode.PARAM_ERROR, "提成单ID不能为空");
        BusinessCommission businessCommission = businessCommissionService.getById(id);
        BusinessAssert.notNull(businessCommission, McnErrorCode.DATA_NOT_FOUND, "查询不到提成单");
        List<BusinessCommissionBatchDeleteDTO> inputList = null;
        try {
            inputList = ExcelUtils.importExcel(multipartFile, BusinessCommissionBatchDeleteDTO.class);
        } catch (Exception e) {
            throw new BusinessException(McnErrorCode.IMPORT_EXCEL_FAILED);
        }
        return Res.ok(businessCommissionService.importBatchDelete(businessCommission, inputList));
    }

    /**
     * 下载失败原因
     * @param response
     * @param fileId
     * @return
     */
    @GetMapping("/excel/download")
    public Res<Object> excelDownload(HttpServletResponse response, String fileId) {
        log.error("收到商务提成Excel下载失败文件请求，fileId={}", fileId);
        businessCommissionService.excelDownload(response, fileId);
        return Res.ok();
    }


    /**
     * 批量删除(编辑)
     *
     * @param ids {@link List<Long>}
     * @return {@link Res}
     */
    @PostMapping(value = "batchDeleteDetail", produces = {"application/json;charset=UTF-8"})
    public Res<Object> batchDeleteDetail(@RequestBody List<Long> ids) {
        return Res.ok(businessCommissionService.batchDeleteDetail(ids));
    }


    /**
     * 提成详情
     *
     * @param page {@link McnPage}
     * @param dto  {@link BusinessInfoQueryDTO}
     * @return {@link Res<BusinessCommissionInfo>}
     */
    @GetMapping(value = "info", produces = {"application/json;charset=UTF-8"})
    public Res<BusinessCommissionInfo> info(McnPage<BusinessCommissionDetail> page, BusinessInfoQueryDTO dto) {
        if (dto.getId() < 115) {
            throw new BusinessException(McnErrorCode.OLD_DATA);
        }
        return Res.ok(businessCommissionService.info(page, dto));
    }


    /**
     * 提成详情导出excel
     *
     * @param id       商务提成id
     * @param response {@link HttpServletResponse}
     * @return {@link Res}
     */
    @GetMapping(value = "exportExcel", produces = {"application/json;charset=UTF-8"})
    public Res<Object> exportExcel(Long id, HttpServletResponse response) {
        try {
            businessCommissionService.exportExcel(id, response);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Res.failed(McnErrorCode.EXPORT_EXCEPTION);
        }
        return Res.ok();
    }


    /**
     * 新建商务提成
     * v2.1版本兼容为保存并发放
     *
     * @param addDTO {@link BusinessCommissionAddDTO}
     * @return {@link Res}
     */
    @PostMapping(value = "/save", produces = {"application/json;charset=UTF-8"})
    public Res<Object> save(@Validated(Add.class) @RequestBody BusinessCommissionAddDTO addDTO) {
        BusinessAssert.notNull(addDTO.getTitle(), McnErrorCode.PARAM_ERROR, "提成单标题不能为空");
        BusinessAssert.maxLength(addDTO.getTitle(), 30, McnErrorCode.PARAM_ERROR, "提成单标题长度最大不能超出%s个字符");
        Long businessId = businessCommissionService.saveBusinessCommission(addDTO);
        log.info("新建商务提成保存后ID:{}", businessId);
        if (Objects.nonNull(addDTO.getBusinessStatus()) && addDTO.getBusinessStatus().equals(BusinessCommissionEnum.ISSUED.code())) {
            //保存并发送放
            businessCommissionService.changeStatus(businessId, addDTO.getBusinessStatus());
        }
        return Res.ok();
    }


    /**
     * 修改状态
     *
     * @param id             商务提成id
     * @param businessStatus 状态
     * @return {@link Res}
     */
    @GetMapping(value = "/change/status", produces = {"application/json;charset=UTF-8"})
    @UrlAuth({"commerceCommission_confirmationProtection","commerceCommission_cancellation"})
    public Res<Object> changeStatus(Long id, Integer businessStatus) {
        businessCommissionService.changeStatus(id, businessStatus);
        return Res.ok();
    }


    /**
     * 商务弹窗
     *
     * @param page            分页
     * @param businessInfoDTO 查询条件
     * @return {@link Res<BusinessInfo>}
     */
    @GetMapping(value = "/businessInfo", produces = {"application/json;charset=UTF-8"})
    public Res<BusinessInfo> businessInfo(McnPage<BusinessCommissionDetail> page, BusinessInfoDTO businessInfoDTO) {
        return Res.ok(businessCommissionService.businessInfo(page, businessInfoDTO));
    }


    /**
     * 商务弹窗导出
     *
     * @param businessInfoDTO 查询条件
     * @param response        {@link HttpServletResponse}
     * @return {@link Res}
     */
    @GetMapping(value = "/exportBusinessInfo", produces = {"application/json;charset=UTF-8"})
    public Res<Object> exportBusinessInfo(BusinessInfoDTO businessInfoDTO, HttpServletResponse response) {
        try {
            businessCommissionService.exportBusinessInfo(businessInfoDTO, response);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Res.failed(McnErrorCode.EXPORT_EXCEPTION);
        }
        return Res.ok();
    }


    /**
     * 商务弹窗 确认提成
     *
     * @param id     提成id
     * @param userId 用户id
     * @param status 状态(1-商务提成，2-部门提成)
     * @return {@link Res}
     */
    @GetMapping(value = "/personalConfirmCommission", produces = {"application/json;charset=UTF-8"})
    public Res<Object> personalConfirmCommission(Long id, Long userId, Integer status) {
        businessCommissionService.personalConfirmCommission(id, userId, status);
        return Res.ok();
    }


    /**
     * 部门负责人弹窗
     *
     * @param page              分页detailList
     * @param departmentInfoDTO 查询条件
     * @return {@link DepartmentInfo}
     */
    @GetMapping(value = "/departmentInfo", produces = {"application/json;charset=UTF-8"})
    public Res<DepartmentInfo> departmentInfo(McnPage<BusinessCommissionDetail> page, DepartmentInfoDTO departmentInfoDTO) {
        return Res.ok(businessCommissionService.departmentInfo(page, departmentInfoDTO));
    }


    /**
     * 部门负责人弹窗导出
     *
     * @param departmentInfoDTO 查询条件
     * @param response          {@link HttpServletResponse}
     * @return {@link Res}
     */
    @GetMapping(value = "/exportDepartInfo", produces = {"application/json;charset=UTF-8"})
    public Res<Object> exportDepartInfo(DepartmentInfoDTO departmentInfoDTO, HttpServletResponse response) {
        try {
            businessCommissionService.exportDepartInfo(departmentInfoDTO, response);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Res.failed(McnErrorCode.EXPORT_EXCEPTION);
        }
        return Res.ok();
    }


    /**
     * 编辑列表(新增)
     *
     * @param dto 传参
     * @return {@link Res}
     */
    @PostMapping(value = "/edit", produces = {"application/json;charset=UTF-8"})
    public Res<Object> edit(@RequestBody BusinessCommissionUpdateDTO dto) {
        return Res.ok(temporaryService.edit(dto));
    }

    /**
     * 编辑明细(编辑)
     *
     * @param dto 传参
     * @return {@link Res}
     */
    @PostMapping(value = "/editDetail", produces = {"application/json;charset=UTF-8"})
    public Res<Object> editDetail(@Validated @RequestBody BusinessCommissionUpdateDTO dto) {
        // BigDecimal personalCommission = dto.getPersonalCommission();
        // BigDecimal dhCommission = dto.getDepartmentHeadCommission();
        // BusinessAssert.isTrue(personalCommission.compareTo(BigDecimal.ZERO) >= 0 && personalCommission.scale() <= 2, McnErrorCode.PARAM_ERROR, "请正确输入-个人提成（>=0 且 小数位<=2）");
        // BusinessAssert.isTrue(dhCommission.compareTo(BigDecimal.ZERO) >= 0 && dhCommission.scale() <= 2, McnErrorCode.PARAM_ERROR, "请正确输入-部门负责人提成（>=0 且 小数位<=2）");
        return Res.ok(businessCommissionService.editDetail(dto));
    }

    /**
     * 提成单详情-基本信息
     * @param id
     * @return
     */
    @GetMapping("/getShortDetail")
    public Res<BusinessCommissionInfoVO> getShortDetail(@RequestParam Long id) {
        return Res.ok(businessCommissionService.getShortDetail(id));
    }

    /**
     * 提成单详情-分页列表
     * @param businessCommissionDetailPageDTO
     * @return
     */
    @PostMapping("/getDetailPage")
    public Res<PageInfo<BusinessCommissionDetail>> getDetailPage(@Validated @RequestBody BusinessCommissionDetailPageDTO businessCommissionDetailPageDTO) {
        return Res.ok(businessCommissionService.getDetailPage(businessCommissionDetailPageDTO));
    }

    /**
     * 提成单详情-确认详情
     * @param businessCheckDetailPageDTO
     * @return
     */
    @PostMapping("/getCheckDetailPage")
    public Res<BusinessConfirmationDetails> getCheckDetailPage(@Validated @RequestBody BusinessCheckDetailPageDTO businessCheckDetailPageDTO) {
        return Res.ok(businessCommissionService.getCheckDetailPage(businessCheckDetailPageDTO));
    }

    /**
     * 发送提成单
     * @param id
     * @return
     */
    @GetMapping("/sendBusinessCommission")
    public Res<Object> sendBusinessCommission(@RequestParam Long id) {
        businessCommissionService.sendBusinessCommission(id);
        return Res.ok();
    }

    /**
     * 导出商务提成单-分页列表
     * @param businessCommissionDetailPageDTO
     * @param response
     * @return
     */
    @PostMapping("/exportDetailPage")
    public Res<Object> exportDetailPage(@Validated @RequestBody BusinessCommissionDetailPageDTO businessCommissionDetailPageDTO, HttpServletResponse response) {
        businessCommissionService.exportDetailPage(businessCommissionDetailPageDTO, response);
        return Res.ok();
    }

    /**
     * 修改商务提成
     *
     * @param dto {@link BusinessCommissionAddDTO}
     * @return {@link Res}
     */
    @PostMapping(value = "/update", produces = {"application/json;charset=UTF-8"})
    public Res<Boolean> update(@Validated(Modify.class) @RequestBody BusinessCommissionAddDTO dto) {
        businessCommissionService.updateData(dto);
        if (Objects.nonNull(dto.getBusinessStatus()) && dto.getBusinessStatus().equals(BusinessCommissionEnum.ISSUED.code())) {
            //保存并发放
            businessCommissionService.changeStatus(dto.getId(), dto.getBusinessStatus());
        }
        return Res.ok(Boolean.TRUE);
    }
}
